/**
 * 有N个物品，每个物品有价格p、收益u和颜色c
 * 在不超过X的花费下选物品，总收益 = 物品的收益和 + K * 不同颜色的数量
 * 问总收益最大是多少
 * 首先将所有颜色相同的物品排成相邻的
 * 令Aij是花费j以内选第i个物品且以前没有选过同颜色的最大收益
 * Bij是花费j以内选第i个物品且以前选过同颜色的最大收益
 * Dij是到i个物品花费j以内的最大收益
 * 
 * for 每个物品i:
 *     令lastk是上一个颜色最后一个物品
 *     for j in [1, X]:
 *         Aij = D[lastk][j-price] + w + K
 *         Bij = D[i - 1][j-price] + w
 *         Dij = max(D[i-1][j], A[i][j], B[i][j])
 * 
 * D[N][X]即答案
 */
#include <bits/stdc++.h>
#include <bits/extc++.h>
using namespace std;

using Real = long double;
using llt = long long;
using vi = vector<int>;
using vll = vector<llt>;
using pii = pair<int, int>;
using pll = pair<llt, llt>;
using i128 = __int128_t;

int N;
int X;
int K;
vi P, U, C;
map<int, vector<pii>> Map;
vector<vll> A;
vector<vll> B;
vector<vll> D;

llt chkadd(llt a , llt b){
    if(-1 == a or -1 == b) return -1;
    return a + b;
}

void chkmax(llt & a, llt b){
    if(a < b) a = b;
}

void work(){
    cin >> N >> X >> K;
    P.assign(N + 1, {});
    U.assign(N + 1, {});
    C.assign(N + 1, {});
    for(int i=1;i<=N;++i){
        cin >> P[i] >> U[i] >> C[i];
        Map[C[i]].emplace_back(P[i], U[i]);
    }
    
    A.assign(N + 1, vll(X + 1, -1));
    B.assign(N + 1, vll(X + 1, -1));
    D.assign(N + 1, vll(X + 1, 0));
    A[0][0] = 0;
    int k = 1;
    for(const auto & p : Map){
        int lastk = k - 1;
        const auto & vec = p.second;


        for(auto it=vec.begin(),et=vec.end();it!=et;++it){
            auto price = it->first;
            auto w = it->second;

            for(int cost=1;cost<=X;++cost){
                if(cost >= price){
                    A[k][cost] = K + D[lastk][cost - price] + w;
                    if(it != vec.begin()){
                        B[k][cost] = D[k - 1][cost - price] + w;
                    }else{
                        B[k][cost] = -1;
                    }
                }
                auto & d = D[k][cost];
                d = D[k - 1][cost];
                chkmax(d, A[k][cost]);
                chkmax(d, B[k][cost]);
            }      
       
            k += 1;

        }

    }
    assert(k == N + 1);
    cout << D[N][X] << endl;
    return;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);	

    int nofkase = 1;
	// cin >> nofkase;
	while(nofkase--) work();
	return 0;
}